package mce.system.model;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import mce.system.configuration.Characteristic;
import mce.system.configuration.ProcessStep;
import mce.system.configuration.definition.CharacteristicDataType;
import mce.system.configuration.definition.CharacteristicValue;
import mce.system.configuration.definition.MceMenu;
import mce.system.configuration.definition.QuoteStepCode;
import mce.system.constant.BapiDataType;
import mce.system.constant.Indicator;
import mce.system.constant.NumberConstant;
import mce.system.constant.StringConstant;
import mce.system.util.StringUtil;

public class Quote {
	private ProcessStep currentStep;// Current step
	private List<ProcessStep> steps;// List of steps for quote processing
	private List<MceMenu> mceMenu; // Left menu for create quote processing
	private Map<String, Characteristic> characteristics;// The list of //
														// characteristics

	public Quote(ProcessStep currentStep, List<ProcessStep> steps,
			List<MceMenu> mceMenu, Map<String, Characteristic> characteristics) {
		this.currentStep = currentStep;
		this.steps = steps;
		this.mceMenu = mceMenu;
		this.characteristics = characteristics;
	}

	public Quote() {
		/**
		 * Add default 2 main steps
		 */
		this.steps = new ArrayList<ProcessStep>();
		// Job information
		ProcessStep jobInformation = new ProcessStep();
		jobInformation.set_GROUP_NAME(QuoteStepCode.JOB_INFORMATION_ID
				.getValue());
		jobInformation.set_GROUP_TEXT(QuoteStepCode.JOB_INFORMATION_TEXT
				.getValue());
		jobInformation
				.set_TEXT_DESCRIPTION(StringConstant.CREATE_QUOTE_NOTIFICATION);
		jobInformation.set_JOBNAME(null);
		jobInformation.setHasBackButton(Boolean.FALSE);
		jobInformation.setBackButtonText(null);
		jobInformation.setHasNextButton(Boolean.TRUE);
		jobInformation.setNextButtonText(StringConstant.NEXT_BUTTON_DEFAULT);
		jobInformation.setBackStepCode(null);
		jobInformation.setNextStepCode(QuoteStepCode.SYSTEM_CONFIGURATION_ID
				.getValue());
		this.steps.add(jobInformation);
		// System Configuration
		ProcessStep systemConfiguration = new ProcessStep();
		systemConfiguration
				.set_GROUP_NAME(QuoteStepCode.SYSTEM_CONFIGURATION_ID
						.getValue());
		systemConfiguration
				.set_GROUP_TEXT(QuoteStepCode.SYSTEM_CONFIGURATION_TEXT
						.getValue());
		systemConfiguration.set_TEXT_DESCRIPTION(null);
		systemConfiguration.set_JOBNAME(null);
		systemConfiguration.setHasBackButton(Boolean.TRUE);
		systemConfiguration
				.setBackButtonText(StringConstant.BACK_BUTTON_DEFAULT);
		systemConfiguration.setHasNextButton(Boolean.TRUE);
		systemConfiguration
				.setNextButtonText(StringConstant.NEXT_BUTTON_DEFAULT);
		systemConfiguration.setBackStepCode(QuoteStepCode.JOB_INFORMATION_ID
				.getValue());
		systemConfiguration.setNextStepCode("B");// Starter
		this.steps.add(systemConfiguration);

		/**
		 * Set step 1 is selected step
		 */
		this.currentStep = this.steps.get(0);
		/**
		 * Generate menu
		 */
		this.mceMenu = new ArrayList<MceMenu>();
		this.mceMenu.add(new MceMenu(QuoteStepCode.JOB_INFORMATION_ID
				.getValue(), QuoteStepCode.JOB_INFORMATION_TEXT.getValue(), 0));
		this.mceMenu.add(new MceMenu(QuoteStepCode.SYSTEM_CONFIGURATION_ID
				.getValue(),
				QuoteStepCode.SYSTEM_CONFIGURATION_TEXT.getValue(), 0));
		this.mceMenu
				.add(new MceMenu(QuoteStepCode.CAR_CONFIGURATION_ID.getValue(),
						QuoteStepCode.CAR_CONFIGURATION_TEXT.getValue(), 0));
		this.mceMenu.add(new MceMenu(QuoteStepCode.RECEIVE_QUOTE_ID.getValue(),
				QuoteStepCode.RECEIVE_QUOTE_TEXT.getValue(), 0));
		Collections.sort(this.mceMenu, StringUtil.alphabeticalOrder);
		/**
		 * Insert non-system characteristics
		 */
		this.characteristics = new HashMap<String, Characteristic>();
		// Sold To
		this.characteristics.put(
				StringConstant.NSC_SOLD_TO_NAME,
				new Characteristic(Boolean.FALSE,
						StringConstant.NSC_SOLD_TO_NAME, BapiDataType.CHAR
								.getType(), StringConstant.NSC_SOLD_TO_TEXT,
						Boolean.FALSE, Boolean.FALSE, Boolean.FALSE,
						Indicator.QUOTE, NumberConstant.ZERO,
						NumberConstant.ZERO, Boolean.FALSE, Boolean.FALSE,
						StringConstant.BLANK, StringConstant.BLANK,
						StringConstant.BLANK, QuoteStepCode.JOB_INFORMATION_ID
								.getValue(), QuoteStepCode.JOB_INFORMATION_ID
								.getValue(), QuoteStepCode.JOB_INFORMATION_TEXT
								.getValue(), 1, CharacteristicDataType.INPUT
								.getType(), null));
		// Contact Person
		this.characteristics.put(StringConstant.NSC_CONTRACT_PERSON_NAME,
				new Characteristic(Boolean.FALSE,
						StringConstant.NSC_CONTRACT_PERSON_NAME,
						BapiDataType.CHAR.getType(),
						StringConstant.NSC_CONTRACT_PERSON_TEXT, Boolean.FALSE,
						Boolean.FALSE, Boolean.FALSE, Indicator.QUOTE,
						NumberConstant.ZERO, NumberConstant.ZERO,
						Boolean.FALSE, Boolean.FALSE, StringConstant.BLANK,
						StringConstant.BLANK, StringConstant.BLANK,
						QuoteStepCode.JOB_INFORMATION_ID.getValue(),
						QuoteStepCode.JOB_INFORMATION_ID.getValue(),
						QuoteStepCode.JOB_INFORMATION_TEXT.getValue(), 2,
						CharacteristicDataType.INPUT.getType(), null));
		// Primary Phone
		this.characteristics.put(StringConstant.NSC_PRIMARY_PHONE_NAME,
				new Characteristic(Boolean.FALSE,
						StringConstant.NSC_PRIMARY_PHONE_NAME,
						BapiDataType.CHAR.getType(),
						StringConstant.NSC_PRIMARY_PHONE_TEXT, Boolean.FALSE,
						Boolean.FALSE, Boolean.FALSE, Indicator.QUOTE,
						NumberConstant.ZERO, NumberConstant.ZERO,
						Boolean.FALSE, Boolean.FALSE, StringConstant.BLANK,
						StringConstant.BLANK, StringConstant.BLANK,
						QuoteStepCode.JOB_INFORMATION_ID.getValue(),
						QuoteStepCode.JOB_INFORMATION_ID.getValue(),
						QuoteStepCode.JOB_INFORMATION_TEXT.getValue(), 3,
						CharacteristicDataType.INPUT.getType(), null));
		// Primary Email
		this.characteristics.put(StringConstant.NSC_PRIMARY_EMAIL_NAME,
				new Characteristic(Boolean.FALSE,
						StringConstant.NSC_PRIMARY_EMAIL_NAME,
						BapiDataType.CHAR.getType(),
						StringConstant.NSC_PRIMARY_EMAIL_TEXT, Boolean.FALSE,
						Boolean.FALSE, Boolean.FALSE, Indicator.QUOTE,
						NumberConstant.ZERO, NumberConstant.ZERO,
						Boolean.FALSE, Boolean.FALSE, StringConstant.BLANK,
						StringConstant.BLANK, StringConstant.BLANK,
						QuoteStepCode.JOB_INFORMATION_ID.getValue(),
						QuoteStepCode.JOB_INFORMATION_ID.getValue(),
						QuoteStepCode.JOB_INFORMATION_TEXT.getValue(), 4,
						CharacteristicDataType.INPUT.getType(), null));
		// Alternate Phone
		this.characteristics.put(StringConstant.NSC_ALTERNATE_PHONE_NAME,
				new Characteristic(Boolean.FALSE,
						StringConstant.NSC_ALTERNATE_PHONE_NAME,
						BapiDataType.CHAR.getType(),
						StringConstant.NSC_ALTERNATE_PHONE_TEXT, Boolean.FALSE,
						Boolean.FALSE, Boolean.FALSE, Indicator.QUOTE,
						NumberConstant.ZERO, NumberConstant.ZERO,
						Boolean.FALSE, Boolean.FALSE, StringConstant.BLANK,
						StringConstant.BLANK, StringConstant.BLANK,
						QuoteStepCode.JOB_INFORMATION_ID.getValue(),
						QuoteStepCode.JOB_INFORMATION_ID.getValue(),
						QuoteStepCode.JOB_INFORMATION_TEXT.getValue(), 5,
						CharacteristicDataType.INPUT.getType(), null));
		// Alternate Email
		this.characteristics.put(StringConstant.NSC_ALTERNATE_EMAIL_NAME,
				new Characteristic(Boolean.FALSE,
						StringConstant.NSC_ALTERNATE_EMAIL_NAME,
						BapiDataType.CHAR.getType(),
						StringConstant.NSC_ALTERNATE_EMAIL_TEXT, Boolean.FALSE,
						Boolean.FALSE, Boolean.FALSE, Indicator.QUOTE,
						NumberConstant.ZERO, NumberConstant.ZERO,
						Boolean.FALSE, Boolean.FALSE, StringConstant.BLANK,
						StringConstant.BLANK, StringConstant.BLANK,
						QuoteStepCode.JOB_INFORMATION_ID.getValue(),
						QuoteStepCode.JOB_INFORMATION_ID.getValue(),
						QuoteStepCode.JOB_INFORMATION_TEXT.getValue(), 6,
						CharacteristicDataType.INPUT.getType(), null));
		// Contact Preference
		List<CharacteristicValue> dataSourceForContactReference = new ArrayList<CharacteristicValue>();

		dataSourceForContactReference.add(new CharacteristicValue(
				StringConstant.BLANK,
				StringConstant.NSC_CONTACT_REFERENCE_NAME, Boolean.TRUE,
				StringConstant.PHONE_VALUE, 1, Boolean.FALSE,
				StringConstant.PHONE_VALUE, StringConstant.PHONE_VALUE,
				StringConstant.PHONE_VALUE, StringConstant.BLANK));// Phone data
																	// source
																	// item
		dataSourceForContactReference.add(new CharacteristicValue(
				StringConstant.BLANK,
				StringConstant.NSC_CONTACT_REFERENCE_NAME, Boolean.FALSE,
				StringConstant.EMAIL_VALUE, 2, Boolean.FALSE,
				StringConstant.EMAIL_VALUE, StringConstant.EMAIL_VALUE,
				StringConstant.EMAIL_VALUE, StringConstant.BLANK));// Email data
																	// source
																	// item
		this.characteristics.put(
				StringConstant.NSC_CONTACT_REFERENCE_NAME,
				new Characteristic(Boolean.FALSE,
						StringConstant.NSC_CONTACT_REFERENCE_NAME,
						BapiDataType.CHAR.getType(),
						StringConstant.NSC_CONTACT_REFERENCE_TEXT,
						Boolean.FALSE, Boolean.FALSE, Boolean.FALSE,
						Indicator.QUOTE, NumberConstant.ZERO,
						NumberConstant.ZERO, Boolean.FALSE, Boolean.FALSE,
						StringConstant.BLANK, StringConstant.BLANK,
						StringConstant.BLANK, QuoteStepCode.JOB_INFORMATION_ID
								.getValue(), QuoteStepCode.JOB_INFORMATION_ID
								.getValue(), QuoteStepCode.JOB_INFORMATION_TEXT
								.getValue(), 7, CharacteristicDataType.SELECT
								.getType(), dataSourceForContactReference));
		// Job Name
		this.characteristics.put(
				StringConstant.NSC_JOB_NAME_NAME,
				new Characteristic(Boolean.FALSE,
						StringConstant.NSC_JOB_NAME_NAME, BapiDataType.CHAR
								.getType(), StringConstant.NSC_JOB_NAME_TEXT,
						Boolean.TRUE, Boolean.FALSE, Boolean.FALSE,
						Indicator.QUOTE, NumberConstant.ZERO,
						NumberConstant.ZERO, Boolean.FALSE, Boolean.FALSE,
						StringConstant.BLANK, StringConstant.BLANK,
						StringConstant.BLANK, QuoteStepCode.JOB_INFORMATION_ID
								.getValue(), QuoteStepCode.JOB_INFORMATION_ID
								.getValue(), QuoteStepCode.JOB_INFORMATION_TEXT
								.getValue(), 8, CharacteristicDataType.INPUT
								.getType(), null));
		// Job Type
		List<CharacteristicValue> dataSourceForJobType = new ArrayList<CharacteristicValue>();
		dataSourceForJobType.add(new CharacteristicValue(StringConstant.BLANK,
				StringConstant.NSC_JOB_TYPE_NAME, Boolean.TRUE,
				StringConstant.E_HYDRAULIC_TEXT, 1, Boolean.FALSE,
				StringConstant.E_HYDRAULIC_VALUE,
				StringConstant.E_HYDRAULIC_VALUE,
				StringConstant.E_HYDRAULIC_VALUE, StringConstant.BLANK));// E-Hydraulic
																			// data
																			// source
		dataSourceForJobType.add(new CharacteristicValue(StringConstant.BLANK,
				StringConstant.NSC_JOB_TYPE_NAME, Boolean.FALSE,
				StringConstant.E_TRACTION_TEXT, 2, Boolean.FALSE,
				StringConstant.E_TRACTION_VALUE,
				StringConstant.E_TRACTION_VALUE,
				StringConstant.E_TRACTION_VALUE, StringConstant.BLANK));// E-Traction
																		// data
																		// source
																		// item
		this.characteristics.put(
				StringConstant.NSC_JOB_TYPE_NAME,
				new Characteristic(Boolean.TRUE,
						StringConstant.NSC_JOB_TYPE_NAME, BapiDataType.CHAR
								.getType(), StringConstant.NSC_JOB_TYPE_TEXT,
						Boolean.FALSE, Boolean.FALSE, Boolean.FALSE,
						Indicator.QUOTE, NumberConstant.ZERO,
						NumberConstant.ZERO, Boolean.FALSE, Boolean.FALSE,
						StringConstant.BLANK, StringConstant.E_HYDRAULIC_VALUE,
						StringConstant.NSC_JOB_TYPE_TEXT,
						QuoteStepCode.JOB_INFORMATION_ID.getValue(),
						QuoteStepCode.JOB_INFORMATION_ID.getValue(),
						QuoteStepCode.JOB_INFORMATION_TEXT.getValue(), 9,
						CharacteristicDataType.SELECT.getType(),
						dataSourceForJobType));
		// Configuration
		List<CharacteristicValue> dataSourceForConfiguration = new ArrayList<CharacteristicValue>();
		dataSourceForConfiguration.add(new CharacteristicValue(
				StringConstant.BLANK, StringConstant.NSC_CONFIGURATION_NAME,
				Boolean.TRUE, StringConstant.SIMPLEX_TEXT, 1, Boolean.FALSE,
				StringConstant.SIMPLEX_VALUE, StringConstant.SIMPLEX_VALUE,
				StringConstant.SIMPLEX_VALUE, StringConstant.BLANK));// E-Hydraulic
																		// data
																		// source
																		// item
		dataSourceForConfiguration.add(new CharacteristicValue(
				StringConstant.BLANK, StringConstant.NSC_CONFIGURATION_NAME,
				Boolean.FALSE, StringConstant.DUPLEX_TEXT, 2, Boolean.FALSE,
				StringConstant.DUPLEX_VALUE, StringConstant.DUPLEX_VALUE,
				StringConstant.DUPLEX_VALUE, StringConstant.BLANK));// E-Traction
																	// data
																	// source
																	// item
		this.characteristics.put(StringConstant.NSC_CONFIGURATION_NAME,
				new Characteristic(Boolean.TRUE,
						StringConstant.NSC_CONFIGURATION_NAME,
						BapiDataType.CHAR.getType(),
						StringConstant.NSC_CONFIGURATION_TEXT, Boolean.FALSE,
						Boolean.FALSE, Boolean.FALSE, Indicator.QUOTE,
						NumberConstant.ZERO, NumberConstant.ZERO,
						Boolean.FALSE, Boolean.FALSE, StringConstant.BLANK,
						StringConstant.SIMPLEX_VALUE,
						StringConstant.NSC_CONFIGURATION_TEXT,
						QuoteStepCode.JOB_INFORMATION_ID.getValue(),
						QuoteStepCode.JOB_INFORMATION_ID.getValue(),
						QuoteStepCode.JOB_INFORMATION_TEXT.getValue(), 10,
						CharacteristicDataType.SELECT.getType(),
						dataSourceForConfiguration));
		// Quantity
		this.characteristics.put(
				StringConstant.NSC_QUANTITY_NAME,
				new Characteristic(Boolean.FALSE,
						StringConstant.NSC_QUANTITY_NAME, BapiDataType.CHAR
								.getType(), StringConstant.NSC_QUANTITY_TEXT,
						Boolean.FALSE, Boolean.FALSE, Boolean.FALSE,
						Indicator.QUOTE, NumberConstant.ZERO,
						NumberConstant.ZERO, Boolean.FALSE, Boolean.FALSE,
						StringConstant.BLANK, String
								.valueOf(NumberConstant.ONE),
						StringConstant.BLANK, QuoteStepCode.JOB_INFORMATION_ID
								.getValue(), QuoteStepCode.JOB_INFORMATION_ID
								.getValue(), QuoteStepCode.JOB_INFORMATION_TEXT
								.getValue(), 11, CharacteristicDataType.INPUT
								.getType(), null));
	}

	/**
	 * @return the currentStep
	 */
	public ProcessStep getCurrentStep() {
		return currentStep;
	}

	/**
	 * @param currentStep
	 *            the currentStep to set
	 */
	public void setCurrentStep(ProcessStep currentStep) {
		this.currentStep = currentStep;
	}

	/**
	 * @return the steps
	 */
	public List<ProcessStep> getSteps() {
		return steps;
	}

	/**
	 * @param steps
	 *            the steps to set
	 */
	public void setSteps(List<ProcessStep> steps) {
		this.steps = steps;
	}

	/**
	 * @return the characteristics
	 */
	public Map<String, Characteristic> getCharacteristics() {
		return characteristics;
	}

	/**
	 * @param characteristics
	 *            the characteristics to set
	 */
	public void setCharacteristics(Map<String, Characteristic> characteristics) {
		this.characteristics = characteristics;
	}

	/**
	 * Sorting for characteristics
	 */

	public void sortByLine() {
		Map<String, Characteristic> sortedMap = new LinkedHashMap<String, Characteristic>();
		// Convert Map to List
		List<Map.Entry<String, Characteristic>> characteristicsList = new LinkedList<Map.Entry<String, Characteristic>>(
				this.characteristics.entrySet());
		// Sort list with comparator, to compare the Map values
		Collections.sort(characteristicsList,
				new Comparator<Map.Entry<String, Characteristic>>() {
					@Override
					public int compare(Map.Entry<String, Characteristic> o1,
							Map.Entry<String, Characteristic> o2) {
						if ((o1.getValue().get_LINE() - o2.getValue()
								.get_LINE()) > 0)
							return 1;
						else
							return -1;
					}
				});
		// Convert sorted map back to a Map
		for (Iterator<Map.Entry<String, Characteristic>> it = characteristicsList
				.iterator(); it.hasNext();) {
			Map.Entry<String, Characteristic> entry = it.next();
			sortedMap.put(entry.getKey(), entry.getValue());
		}
		this.characteristics = sortedMap;
	}

	/**
	 * @return the mceMenu
	 */
	public List<MceMenu> getMceMenu() {
		return mceMenu;
	}

	/**
	 * @param mceMenu
	 *            the mceMenu to set
	 */
	public void setMceMenu(List<MceMenu> mceMenu) {
		this.mceMenu = mceMenu;
	}

	public int getStepByGroupName(String groupName) {
		for (int i = 0; i < this.steps.size(); i++) {
			if (this.steps.get(i).get_GROUP_NAME().equals(groupName))
				return i;
		}
		return 0;
	}
}
